import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:jyofservice/bean/LevelData.dart';
import 'package:jyofservice/bean/Node.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jyofservice/bean/tree_simple_data_entity.dart';
import 'package:jyofservice/generated/json/base/json_convert_content.dart';
import 'package:jyofservice/util/AesUtil.dart';
import 'package:jyofservice/util/webconfig.dart';

class LevelTree extends StatefulWidget {
  @override
  _LevelTreeState createState() => _LevelTreeState();
}

class _LevelTreeState extends State<LevelTree> {
  ///保存所有数据的list
  List<Node> list = [];

  ///保存当前展示数据的list;
  List<Node> expand = [];

  ///保存list的下标的list，用来做标记用
  List<String?> mark = [];

  ///第一个节点的index
  // int nodeId = 1;
  List<Node>? keep;
  late SharedPreferences sharedPreferences;
  String? key;
  bool isloading = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    init().then((onValue) {
      _buildData().then((onValue) {
        if (onValue.length != 0) {
          _parseGroups(onValue);

          _addRoot();
          if (mounted) {
            isloading = true;
            setState(() {});
          }
        }
      });
    });
  }

  Future init() async {
    sharedPreferences = await SharedPreferences.getInstance();
    key = sharedPreferences.getString("key");
    return key;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('发布范围'),
        actions: <Widget>[
          TextButton(
            onPressed: () {
              isloading = false;
              setState(() {

              });
              List<Node> selectNode = getAllSelectData();
              isloading = true;
              Navigator.pop(context, selectNode);
            },
            child: Text(
              "确定",
              style: TextStyle(
                  color: Colors.white, fontSize: ScreenUtil().setSp(35)),
            ),
          )
        ],
      ),
      body:Stack(
        children: <Widget>[
          Container(
            padding: const EdgeInsets.all(5),
            child: Column(
              children: <Widget>[
                Expanded(
                  child: ListView(
                    children: _buildNode(expand),
                  ),
                ),
              ],
            ),
          ),Offstage(
            offstage: isloading,
            child: SpinKitFadingCircle(
              color: Colors.blue,
              size: 50.0,
            ),
          )
        ],
      )
    );
  }

  List<Widget> _buildNode(List<Node> nodes) {
    List<Widget> widgets = [];
    if (nodes != null && nodes.length > 0) {
      for (Node node in nodes) {
        widgets.add(Column(
          children: <Widget>[
            Container(
              // color: Color.fromRGBO(234, 244, 255, 1),
              padding: EdgeInsets.only(left: (node.depth) * 15.0),
              child: Row(
                children: <Widget>[
                  TextButton(
                    child: Image.asset(
                      node.isselect
                          ? "images/yixuanzhong.png"
                          : "images/weixuanzhong.png",
                      width: ScreenUtil().setWidth(40),
                    ),
                    onPressed: () {
                      //选择
                      _selectNode(node.nodeId);
                      if (mounted) {
                        setState(() {});
                      }
                    },
                  ),
                  Expanded(
                    flex: 1,
                    child: Text(
                      node.type == Node.typeOrgan
                          ? (node.object as Group).name!
                          : (node.object as Member).name!,
                      style: TextStyle(
                          color: Colors.black,
                          fontSize: ScreenUtil().setSp(30)),
                    ),
                  ),
                  TextButton(
                    child: Image.asset(
                      node.type == Node.typeOrgan
                          ? node.expand
                              ? "images/shangla.png"
                              : "images/xiala.png"
                          : "images/wuxing.png",
                      width: ScreenUtil().setWidth(30),
                    ),
                    onPressed: () {
                      //选择
                      if (node.type == Node.typeOrgan) {
                        if (node.expand) {
                          //之前是扩展状态，收起列表
                          node.expand = false;
                          _collect(node.nodeId);
                        } else {
                          //之前是收起状态，扩展列表
                          setState(() {
                            isloading = false;
                          });
                          node.expand = true;
                          if (node.isfirst) {
                            if (node.levela == "D" ||
                                node.levela == "E" ||
                                node.levela == "F" ||
                                node.levela == "G" ||
                                node.levela == "H" ||
                                node.levela == "I" ||
                                node.levela == "J") {
                              _getChildData(node);
                              node.isfirst = false;
                            } else {
                              _expand(node.nodeId);
                            }
                          } else {
                            _expand(node.nodeId);
                          }
                        }
                        if (mounted) {
                          isloading = true;
                          setState(() {});
                        }
                      }
                    },
                  ),
                ],
              ),
            ),
            Container(
              color: Colors.grey,
              height: ScreenUtil().setHeight(1),
            )
          ],
        ));
      }
    }
    return widgets;
  }

  void _parseGroups(List<Group?> onValue) {
    List<Group?> groups = onValue;
    for (Group? group in groups) {
      _parseGroup(group!);
    }
  }

  //递归解析原始数据，将group递归，记录其深度，nodeid和fatherid，将根节点的fatherid置未-1,
  void _parseGroup(Group group, {int depth = 0, String? fatherId}) {
    list.add(Node(false, depth, Node.typeOrgan, group.no, group.pid, false,
        group, group.levela, true));
    List<Node<Member>> members = [];
    if (group.members != null) {
      for (Member member in group.members) {
        members.add(Node(false, depth + 1, Node.typeMember, member.no,
            member.pid, false, member, member.levela, true));
      }
    }
    list.addAll(members);
    if (group.subGroups != null) {
      for (Group group in group.subGroups) {
        _parseGroup(group, depth: depth + 1, fatherId: group.no);
      }
    }
  }

  ///扩展机构数，id代表被点击的机构id
  ///遍历整个list，如果fatherid==nodeid将直接挂在该机构下面的节点增加到一个临时列表中
  ///然后将临时列表插入到被点击的机构下面
  void _expand(String? id) {
    //保存到临时列表
    List<Node> tmp = [];
    for (Node node in list) {
      if (node.fatherId == id) {
        tmp.add(node);
      }
    }
    //找到插入点，将子节点插入到该点
    int index = -1;
    int length = expand.length;
    for (int i = 0; i < length; i++) {
      if (id == expand[i].nodeId) {
        index = i + 1;
        break;
      }
    }
    expand.insertAll(index, tmp);
  }

  ///收起机构树：id代表被点击的id
  ///遍历整个expand列表，将直接和间接挂在该节点下的节点标记
  ///将这些被标记节点删除即可，此处用到的是将没有被标记的节点加入到新的列表中
  void _collect(String? id) {
    //清楚之前的标记
    mark.clear();
    //标记
    _mark(id);
    //重新对expand赋值
    List<Node> tmp = [];
    for (Node node in expand) {
      if (mark.indexOf(node.nodeId) < 0) {
        tmp.add(node);
      } else {
        node.expand = false;
      }
    }
    expand.clear();
    expand.addAll(tmp);
  }

  ///标记，在收起机构树的时候用到
  void _mark(String? id) {
    for (Node node in expand) {
      if (id == node.fatherId) {
        if (node.type == Node.typeOrgan) {
          _mark(node.nodeId);
        }
        mark.add(node.nodeId);
      }
    }
  }

  ///多选
  void _selectNode(String? id) {
    for (Node node in list) {
      if (node.nodeId == id) {
        node.isselect = !node.isselect;
        if (node.type == Node.typeOrgan) {
          _selectGroupNode(node);
        }
      }
    }
  }

  ///子节点进行选择
  void _selectGroupNode(Node node) {
    for (Node membernode in list) {
      if (membernode.fatherId == node.nodeId) {
        membernode.isselect = !membernode.isselect;
        if (membernode.type == Node.typeOrgan) {
          _selectGroupNode(membernode);
        }
      }
    }
  }

  ///增加根
  void _addRoot() {
    for (Node node in list) {
      if (node.fatherId == "0") {
        expand.add(node);
      }
    }
  }

  Future<List<Group?>> _buildData() async {
    String aesData = await (AesUtil.encodeBase64());
    var data = {
      "key": key,
      "levela": "D",
      "xzlevela": "B",
      "minlevela": "",
      "ClientType": "phone",
      "ClientKey": aesData
    };

    Group? root = null;

    Response response = await Dio()
        .post(WebConfig().baseUrl + "Tree/GetStartSimpleHouseTree", data: data);
    print(response.data.toString());

    if (response.data["Code"] == "200") {
      TreeSimpleDataEntity treeSimpleDataEntity =
          TreeSimpleDataEntity.fromJson(response.data);
      for (int i = 0; i < treeSimpleDataEntity.data!.length; i++) {
        if (treeSimpleDataEntity.data![i].levela == "A") {
          root = Group([], [],
              treeSimpleDataEntity.data![i].name,
              treeSimpleDataEntity.data![i].pId,
              treeSimpleDataEntity.data![i].no,
              treeSimpleDataEntity.data![i].levela);
          // nodeId = int.parse(root.no);
          break;
        }
      }
      _paseData(treeSimpleDataEntity, root);
    }

    List<Group?> groups = [];
    groups.add(root);
    return groups;
  }

  _paseData(TreeSimpleDataEntity treeSimpleDataEntity, Group? root) {
    for (int i = 0; i < treeSimpleDataEntity.data!.length; i++) {
      if (treeSimpleDataEntity.data![i].pId == root!.no) {
        if (treeSimpleDataEntity.data![i].isParent!) {
          Group group = Group([], [],
              treeSimpleDataEntity.data![i].name,
              treeSimpleDataEntity.data![i].pId,
              treeSimpleDataEntity.data![i].no,
              treeSimpleDataEntity.data![i].levela);
          _paseData(treeSimpleDataEntity, group);
          root.subGroups.add(group);
        } else {
          root.members.add(Member(
              treeSimpleDataEntity.data![i].name,
              treeSimpleDataEntity.data![i].pId,
              treeSimpleDataEntity.data![i].no,
              treeSimpleDataEntity.data![i].levela));
        }
      }
    }
  }

  Future _getChildData(Node node) async {
    String aesData = await (AesUtil.encodeBase64());
    var data = {
      "key": key,
      "levela": node.levela,
      "no": node.nodeId,
      "ClientType": "phone",
      "ClientKey": aesData
    };
    print(data.toString());

    Response response = await Dio().post(
        WebConfig().baseUrl + "Tree/GetHouseTreeDataFast",
        data: data);
    print("child:" + response.data.toString());
    if (response.data["Code"] == "200") {
      TreeSimpleDataEntity treeSimpleDataEntity =
          TreeSimpleDataEntity.fromJson(response.data);
      _paseChildData(treeSimpleDataEntity, node.object);
      _parseChild(node.object, node);
    }
    setState(() {
      _expand(node.nodeId);
    });
  }

  _parseChild(Group group, Node node) {
    List<Node<Member>> members = [];
    if (group.members != null) {
      for (Member member in group.members) {
        members.add(Node(false, node.depth + 1, Node.typeMember, member.no,
            member.pid, false, member, member.levela, true));
      }
    }
    list.addAll(members);
    print("size:+" + list.length.toString());

    if (group.subGroups != null) {
      for (Group childgroup in group.subGroups) {
        list.add(Node(false, node.depth + 1, Node.typeOrgan, childgroup.no,
            childgroup.pid, false, childgroup, childgroup.levela, true));
      }
      print("size:+" + list.length.toString());
    }
  }

  _paseChildData(TreeSimpleDataEntity treeSimpleDataEntity, Group root) {
    for (int i = 0; i < treeSimpleDataEntity.data!.length; i++) {
      if (treeSimpleDataEntity.data![i].pId == root.no) {
        if (treeSimpleDataEntity.data![i].isParent!) {
          Group group = Group([], [],
              treeSimpleDataEntity.data![i].name,
              treeSimpleDataEntity.data![i].pId,
              treeSimpleDataEntity.data![i].no,
              treeSimpleDataEntity.data![i].levela);
          root.subGroups.add(group);
        } else {
          root.members.add(Member(
              treeSimpleDataEntity.data![i].name,
              treeSimpleDataEntity.data![i].pId,
              treeSimpleDataEntity.data![i].no,
              treeSimpleDataEntity.data![i].levela));
        }
      }
    }
  }

  List<Node> getAllSelectData() {
    List<Node> selectNode = [];
    for (Node node in list) {
      if (node.isselect) {
        if (node.fatherId == "0") {
          selectNode.clear();
          selectNode.add(node);
          break;
        } else {
          getParentSelct(node, selectNode);
        }
      }
    }
    return selectNode;
  }

  void getParentSelct(Node node, List<Node> allSelect) {
    for (Node temp in list) {
      if (temp.nodeId == node.fatherId) {
        if (temp.isselect) {
          getParentSelct(temp, list);
        } else {
          bool isAdd = true;
          for (Node temp in allSelect) {
            if (temp.nodeId == node.nodeId) {
              isAdd = false;
              break;
            }
          }
          if (isAdd) {
            print(node.type == Node.typeOrgan
                ? (node.object as Group).name
                : (node.object as Member).name);
            allSelect.add(node);
          }
        }
        break;
      }
    }
  }

}
